package com.mahiru.mahiruaiagent.controller;

import com.mahiru.mahiruaiagent.agent.MahiruManus;
import com.mahiru.mahiruaiagent.app.ChatApp;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;

/**
 * @Author Enkidu
 * @Date 2025/7/10 00:30
 */
@RestController
@RequestMapping("/ai")
public class AiController {

    @Resource
    private ChatApp chatApp;

    @Autowired
    private ToolCallback[] allTools;

    @Autowired
    private ChatModel dashscopeChatModel;

    @Autowired
    private ToolCallbackProvider toolCallbackProvider;

    /**
     * AI基础对话 （同步调用）
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping("/chat/sync")
    public String doChatWithSync(String message, String chatId) {
        return chatApp.doChat(message, chatId);
    }

    /**
     * AI基础对话 （SSE 流式异步调用）
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/chat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> doChatWithSSE(String message, String chatId) {
        return chatApp.doChatByStream(message, chatId);
    }

    /**
     * AI基础对话 （SSE 流式异步调用）
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/chat/server_sent_event")
    public Flux<ServerSentEvent<String>> doChatWithServerSentEvent(String message, String chatId) {
        return chatApp.doChatByStream(message, chatId)
                .map(chunk -> ServerSentEvent.<String>builder()
                        .data(chunk)
                        .build());
    }

    /**
     * AI基础对话 （SSE 流式异步调用）
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/chat/sse_emitter")
    public SseEmitter doChatWithSseEmitter(String message, String chatId) {
        // 3分钟超时时间
        SseEmitter sseEmitter = new SseEmitter(180000L);
        // 获取 Flux 响应式数据流 通过订阅推送给SseEmitter
        chatApp.doChatByStream(message, chatId)
                .subscribe(
                        chunk -> {
                            try {
                                sseEmitter.send(chunk);
                            } catch (IOException e) {
                                sseEmitter.completeWithError(e);
                            }
                        }, sseEmitter::completeWithError, sseEmitter::complete);
        return sseEmitter;
    }

    @GetMapping("/manus/chat")
    public SseEmitter doChatWithManus(String message) {
        MahiruManus mahiruManus = new MahiruManus(allTools, dashscopeChatModel, toolCallbackProvider);
        return mahiruManus.runStream(message);
    }
}
